/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_task.h
 * @brief    任务服务（仅在任务中调用）
 * @author   迟凯峰
 * @version  V1.0.2
 * @date     2023.10.26
 ******************************************************************************/

#ifndef __SV_TASK_H
#define __SV_TASK_H

s_bool_t   su_enter_critical (void);
s_bool_t   su_exit_critical  (void);
void       su_task_scheduling(void);

s_ecode_t  su_startup_task   (s_taskhand_tsp hand, s_u8_t status);
s_ecode_t  su_suspend_task   (s_tasknode_tsp node);
s_ecode_t  su_resume_task    (s_tasknode_tsp node);
s_ecode_t  su_resume_suspend (s_tasknode_tsp node);
s_ecode_t  su_delete_task    (s_tasknode_tsp node);
s_ecode_t  su_set_taskpri    (s_tasknode_tsp node, s_u8_t pri);
s_bool_t   su_set_block      (s_tasknode_tsp node, s_delay_t tick);
s_bool_t   su_clear_block    (s_tasknode_tsp node);
void       su_delay          (s_delay_t tick);
s_bool_t   su_take_mutex     (s_mutex_tsp mut, s_delay_t tick);
s_ecode_t  su_give_mutex     (s_mutex_tsp mut);
s_bool_t   su_wait_binary    (s_bool_t _OBJ_MEM_ *bin, s_delay_t tick);
s_bool_t   su_take_binary    (s_bool_t _OBJ_MEM_ *bin, s_delay_t tick);
s_bool_t   su_take_semaphore (s_sem_tsp sem, s_delay_t tick);
void       su_give_semaphore (s_sem_tsp sem);
m_fetion_t su_recv_fetion    (m_fetion_t _OBJ_MEM_ *ft, s_delay_t tick);
s_bool_t   su_recv_taskmsg   (m_taskmsg_t _OBJ_MEM_ *nmf, s_delay_t tick);
s_bool_t   su_recv_mail      (s_bool_t _OBJ_MEM_ *gf, s_delay_t tick);
void       su_send_mail      (void _OBJ_MEM_ *gm, void *lm, size_t size, s_bool_t _OBJ_MEM_ *gf);
void      *su_recv_msg       (s_msgqueue_tsp queue, s_delay_t tick);
s_ecode_t  su_send_msg       (s_msgqueue_tsp queue, void *msg);
s_bool_t   su_query_group    (void _OBJ_MEM_ *p, s_u8_t size);
s_bool_t   su_wait_group     (void _OBJ_MEM_ *p, s_u8_t size, s_delay_t tick);
void       su_gvar_write     (void *gv, void *lv, size_t size);
void       su_gvar_selfope   (void *gv, void *lv, s_voidvoid_tfp fp);

s_bool_t   su_init_mempool   (s_thrmem_tsp p, size_t size);
void _MALLOC_MEM_ *su_talloc (s_thrmem_tsp p, size_t size);
void _MALLOC_MEM_ *su_xalloc (void _MALLOC_MEM_ *p);



/*
 * 任务
 */

/* 启动任务 */
#define sUSV_StartTask(hand, status) \
( \
	su_enter_critical() || true ? su_startup_task(hand, !status ? OS_STATUS_READY : OS_STATUS_SUSPENDED) : false \
)

/* 挂起任务 */
#define	sUSV_SuspendTask(node) \
( \
	su_enter_critical() || true ? su_suspend_task(node) : false \
)

/* 恢复任务 */
#define	sUSV_ResumeTask(node) \
( \
	su_enter_critical() || true ? su_resume_task(node) : false \
)

/* 恢复指定任务并挂起自身任务 */
#define	sUSV_ResumeSuspend(node) \
( \
	su_enter_critical() || true ? su_resume_suspend(node) : false \
)

/* 删除任务 */
#define	sUSV_DeleteTask(node) \
( \
	su_enter_critical() || true ? su_delete_task(node) : false \
)

/* 设置任务优先级 */
#define	sUSV_SetTaskPri(node, pri) \
( \
	su_enter_critical() || true ? su_set_taskpri(node, pri) : false \
)

/* 设置阻塞（时间）*/
#define sUSV_SetBlock(node, tc) \
( \
	su_enter_critical() || true ? su_set_block(node, tc) : false \
)

/* 清除阻塞（状态）*/
#define sUSV_ClearBlock(node) \
( \
	su_enter_critical() || true ? su_clear_block(node) : false \
)

/* 自身任务延时 */
#define	sUSV_Delay(tc) \
do{ \
	uEnterCritical; \
	su_delay(tc); \
}while(false)



/*
 * 定时
 */

/* 定时中断 */
#define	sUSV_TimInt(tmid, tc) \
do{ \
	uEnterCritical; \
	s_timint_loader[tmid] = s_timint_reload[tmid] = tc; \
	uExitCritical; \
}while(false)

/* 定时查询 */
#define	sUSV_TimQry(tmid, tc) \
do{ \
	uEnterCritical; \
	s_timqry_loader[tmid] = s_timqry_reload[tmid] = tc; \
	uExitCritical; \
}while(false)



/*
 * 互斥信号量
 */

/* 获取 */
#define	sUSV_TakeMut(mut, tc) \
( \
	su_enter_critical() || true ? su_take_mutex(&mut, tc) : false \
)

/* 释放 */
#define sUSV_GiveMut(mut) \
( \
	su_enter_critical() || true ? su_give_mutex(&mut) : false \
)



/*
 * 二值信号量
 */

/* 等待 */
#define	sUSV_WaitBin(bin, tc) \
( \
	su_enter_critical() || true ? su_wait_binary((s_bool_t *)&bin, tc) : false \
)

/* 获取 */
#define	sUSV_TakeBin(bin, tc) \
( \
	su_enter_critical() || true ? su_take_binary((s_bool_t *)&bin, tc) : false \
)



/*
 * 计数信号量
 */

/* 获取 */
#define sUSV_TakeSem(sem, tc) \
( \
	su_enter_critical() || true ? su_take_semaphore(&sem, tc) : false \
)

/* 释放 */
#define sUSV_GiveSem(sem) \
do{ \
	uEnterCritical; \
	su_give_semaphore(&sem); \
}while(false)



/*
 * 飞信
 */

/* 接收飞信 */
#define sUSV_RecvFetion(tbox, tc) \
( \
	su_enter_critical() || true ? su_recv_fetion((m_fetion_t *)&tbox, tc) : false \
)



/*
 * 私信
 */

/* 接收私信 */
#define	sUSV_RecvTaskMsg(tc) \
( \
	su_enter_critical() || true \
	? su_recv_taskmsg(&m0_, tc) \
		? s_memcpy(&m0 + 1, &m0_ + 1, MCUCFG_TASKMSG_SIZE) || true \
			? su_exit_critical() \
			: su_exit_critical() \
		: false \
	: false \
)

/* 发送私信 */
#define	sUSV_SendTaskMsg(task) \
	uEnterCritical; \
	s_sign_send_taskmsg = true; \
	MCUCFG_TASKMSG_PSP; \
	while(true) \
		if(!s_sign_send_taskmsg){ \
			uExitCritical; \
			break; \
		} \
		else \
			task(MCUCFG_TASKMSG_VAL, 



/*
 * 消息邮箱
 */

/* 接收邮件 */
#define sUSV_RecvMail(mail, mbox, tc) \
( \
	su_enter_critical() || true \
	? su_recv_mail((s_bool_t *)&mbox##_gnmf, tc) \
		? s_memcpy(mail, &mbox, sizeof(mbox)) || true \
			? su_exit_critical() \
			: su_exit_critical() \
		: false \
	: false \
)

/* 发送邮件 */
#define sUSV_SendMail(mbox, mail) \
do{ \
	uEnterCritical; \
	su_send_mail(&mbox, mail, sizeof(mbox), (s_bool_t *)&mbox##_gnmf); \
}while(false)



/*
 * 消息队列
 */

/* 接收消息 */
#define	sUSV_RecvMsg(que, tc) \
( \
	su_enter_critical() || true ? su_recv_msg(que, tc) : NULL \
)

/* 发送消息 */
#define	sUSV_SendMsg(que, msg) \
( \
	su_enter_critical() || true ? su_send_msg(que, msg) : false \
)



/*
 * 事件标志组
 */

/* 查询标志组 */
#define	sUSV_QueryFlagGroup(group) \
( \
	su_enter_critical() || true ? su_query_group((void *)&group, sizeof(group)) : false \
)

/* 等待标志组 */
#define	sUSV_WaitFlagGroup(group, tc) \
( \
	su_enter_critical() || true ? su_wait_group((void *)&group, sizeof(group), tc) : false \
)

/* 清除标志组 */
#define sUSV_ClearFlagGroup(group) \
do{ \
	uEnterCritical; \
	sizeof(group) == 1 ? *(s_u8_t  *)&group = false : OS_NOPx1; \
	sizeof(group) == 2 ? *(s_u16_t *)&group = false : OS_NOPx1; \
	sizeof(group) == 4 ? *(s_u32_t *)&group = false : OS_NOPx1; \
	uExitCritical; \
}while(false)

/* 写标志位 */
#define sUSV_WriteFlagBit(group, bit, value) \
do{ \
	uEnterCritical; \
	group.bit = value; \
	uExitCritical; \
}while(false)



/*
 * 全局变量
 */

/* 读全局变量 */
#define sUSV_ReadGVar(gv) \
( \
	su_enter_critical() || true ? gv : gv \
); \
uExitCritical

/* 读全局数组 */
#define sUSV_ReadGAry(lp, gp, size) \
do{ \
	uEnterCritical; \
	s_memcpy(lp, gp, size); \
	uExitCritical; \
}while(false)

/* 读全局字符串 */
#define sUSV_ReadGStr(ls, gs) \
do{ \
	uEnterCritical; \
	s_strcpy(ls, gs); \
	uExitCritical; \
}while(false)

/* 全局变量写访问 */
#define sUSV_WriteGVar(gp, lp, size) \
do{ \
	uEnterCritical; \
	su_gvar_write(gp, lp, size); \
}while(false)

/* 全局变量自运算 */
#define sUSV_SelfOpe(gv, type, fp) \
do{ \
	static type lv; \
	uEnterCritical; \
	lv = gv; \
	su_gvar_selfope((void *)&gv, (void *)&lv, fp); \
}while(false)



/*
 * 进程内存
 */

/* malloc */
#define	sUSV_Malloc(size) \
( \
	su_enter_critical() || true ? su_xalloc(s_malloc(size)) : NULL \
)

/* calloc */
#define	sUSV_Calloc(nmemb, size) \
( \
	su_enter_critical() || true ? su_xalloc(s_calloc(nmemb, size)) : NULL \
)

/* realloc */
#define	sUSV_Realloc(p, size) \
( \
	su_enter_critical() || true ? su_xalloc(s_realloc(p, size)) : NULL \
)

/* free */
#define	sUSV_Free(p) \
do{ \
	uEnterCritical; \
	s_free(p); \
	uExitCritical; \
}while(false)



/*
 * 线程内存
 */

/* 初始化线程内存池 */
#define	sUSV_InitMempool(size) \
( \
	su_enter_critical() || true ? su_init_mempool(&u_thrmem, size) : false \
)

/* 线程内存分配 */
#define	sUSV_Talloc(size) \
( \
	su_enter_critical() || true ? su_xalloc(su_talloc(&u_thrmem, size)) : NULL \
)

/* 释放线程内存池 */
#define	sUSV_FreeMempool \
do{ \
	sUSV_Free(u_thrmem.head); \
	u_thrmem.head = u_thrmem.move = NULL; \
}while(false)



#endif
